package com.example.othree.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.othree.common.*;
import com.example.othree.entity.User;
import com.example.othree.entity.UserLoginParam;
import com.example.othree.service.MailService;
import com.example.othree.service.UserService;
import com.example.othree.util.RedisUtils;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@RestController
@CrossOrigin
@RequestMapping("/api")
public class UserController {
    @Value("Authorization")
    private String tokenHeader;
    @Value("Othree")
    private String tokenHead;
    @Autowired
    private UserService userService;
    @Autowired
    private MailService mailService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private MailController mailController;
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @ApiOperation(value = "刷新token")
    @RequestMapping(value = "/refreshToken/{username}", method = RequestMethod.GET)
    @ResponseBody
    public R refreshToken(HttpServletRequest request, @PathVariable String email) {
        String token = request.getHeader(tokenHeader);
        String refreshToken = userService.refreshToken(token, email);
        if (refreshToken == null) {
            return R.error().message("token已经过期！");
        }
        Map<String, Object> tokenMap = new HashMap<>();
        tokenMap.put("token", refreshToken);
        tokenMap.put("tokenHead", tokenHead);
        return R.ok().data(tokenMap);
    }
    @PostMapping("/user/login")
    public R login(@RequestBody UserLoginParam userLoginParam) {
        String token = userService.login(userLoginParam.getEmail(), userLoginParam.getPassword());
        if (token == null) {
            return R.error().message("用户名或密码错误");
        }
        Map<String, Object> tokenMap = new HashMap<>();
        tokenMap.put("token", token);
        tokenMap.put("tokenHead", tokenHead);
        return R.ok().data(tokenMap);
    }

    @GetMapping("/user/list")
    public List<User> list() {
        return userService.list();
    }

    @PostMapping("/user/delete/{id}")
    public R delete(@PathVariable Integer id){
        return userService.removeById(id) ? R.ok() : R.error();
    }

    @PostMapping("/save")
    public R save(@RequestBody User user) {
        // 1. 检查用户名是否存在
        List<User> list = userService.lambdaQuery().eq(User::getUsername, user.getUsername()).eq(User::getIsRoot, 0).list();
        if (list.size() > 0) {
            return R.error().message("用户名已存在");
        }
        // 2. 检查邮箱是否存在
        list = userService.lambdaQuery().eq(User::getEmail, user.getEmail()).eq(User::getIsRoot, 0).list();
        if (list.size() > 0) {
            return R.error().message("该邮箱已被注册，请勿重复注册！"); // 修改了提示语
        }

        // 3. +++ 核心修改：在保存之前，对明文密码进行加密 +++
        String encodedPassword = bCryptPasswordEncoder.encode(user.getPassword());
        user.setPassword(encodedPassword); // 将User对象中的密码替换为加密后的密码

        // 4. 保存用户
        return userService.save(user) ? R.ok() : R.error();
    }

    @PostMapping("/user/update")
    public R update(@RequestBody User user) {
        List<User> list = userService.lambdaQuery().eq(User::getUsername, user.getUsername()).ne(User::getId, user.getId()).eq(User::getIsRoot, 0).list();
        if (list.size() > 0) {
            return R.error().message("名称重复，换一个吧！");
        }
        list = userService.lambdaQuery().eq(User::getEmail, user.getEmail()).ne(User::getId, user.getId()).eq(User::getIsRoot, 0).list();
        if (list.size() > 0) {
            return R.error().message("邮箱重复了，换一个吧！");
        }
        return userService.updateById(user) ? R.ok() : R.error();
    }

    @PostMapping("/user/listPage")
    @ApiOperation("查询、分页")
    public R listPage(@RequestBody PageParam pageParam) {
        HashMap param = pageParam.getParam();
        String email = param.get("email").toString();
        String username = param.get("username").toString();

        Page<User> page = new Page();
        page.setCurrent(pageParam.getPageNum());
        page.setSize(pageParam.getPageSize());

        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        if(StringUtils.isNotBlank(email) && !"null".equals(email)) {
            lambdaQueryWrapper.eq(User::getEmail, email);
        }
        if(StringUtils.isNotBlank(username) && !"null".equals(username)) {
            lambdaQueryWrapper.eq(User::getUsername, username);
        }
        IPage result = userService.PageList(page, lambdaQueryWrapper);
        return R.ok().data("result", result);
    }

    @PostMapping("/user/register")
    public R register(@RequestBody RegisterEntity entity) {
        String username = entity.getUsername();
        String emailCode = entity.getEmailCode();
        if(redisUtils.hasKey(RedisTransKey.getEmailKey(username))){
            Object o = redisUtils.get(RedisTransKey.getEmailKey(username));
            System.out.println(o.toString());
            EmailCodeEntity emailCodeEntity = JSON.parseObject(o.toString(), EmailCodeEntity.class);
            if(username.equals(emailCodeEntity.getUsername())){
                System.out.println("111");
                if(emailCode.equals(emailCodeEntity.getEmailCode())){
                    //开始封装用户并进行存储
                    System.out.println("222");
                    User userEntity = new User();
                    userEntity.setEmail(entity.getEmail());
                    userEntity.setUsername(entity.getUsername());
                    userEntity.setPassword(entity.getPassword());
                    userEntity.setIsRoot(0);
                    userEntity.setIsNotify(0);
                    userService.save(userEntity);
//                    redisUtils.del(RedisTransKey.getEmailKey(username));
                }else {
                    return R.error();
                }
            }else {
                return R.error();
            }
        }else {
            return R.error();
        }
        return R.ok();
    }

    @GetMapping("/user/is_login")
    @CrossOrigin(origins = {"http://121.42.179.58:8000", "http://47.114.138.125:8012", "http://47.114.138.125:8011","http://10.48.37.228:8090", "http://10.48.37.228:8089"}, allowedHeaders = "Authorization", allowCredentials = "true")
    public R IsLogin(HttpServletRequest httpServletRequest) {

        Cookie[] cookies = httpServletRequest.getCookies();
        if (cookies == null) {
            return R.error().message("未登录！");
        }
        String token = null;
        for (Cookie cookie : cookies) {
            if ("token".equals(cookie.getName())) {
                token = cookie.getValue();
            }
        }
        
        String token_value = redisUtils.get(token).toString();
        System.out.println(token);
        System.out.println(token_value);
        if (token_value.equals(token)) {
            return R.ok().message("登录成功");
        }
        return R.error().message("失败");
    }

    @GetMapping("/user/logout")
    @CrossOrigin(origins = {"http://121.42.179.58:8000", "http://47.114.138.125:8012", "http://47.114.138.125:8011", "http://10.48.37.228:8090", "http://10.48.37.228:8089" , " http://10.48.37.228:8088"}, allowedHeaders = "Authorization", allowCredentials = "true")
    public R logout(HttpServletRequest httpServletRequest) {
        Cookie[] cookies = httpServletRequest.getCookies();

        if (cookies == null) {
            return R.error().message("未登录！");
        }
        String token = null;
        for (Cookie cookie : cookies) {
            if ("token".equals(cookie.getName())) {
                token = cookie.getValue();
            }
        }
        System.out.println(token);
        redisUtils.del(token);
        return R.ok().message("成功注销");
    }


}
